import { defineStore } from 'pinia'
// defineStore 是 Pinia 提供的 API，用于定义一个 store。通过这个 API，你可以创建一个全局的状态管理容器，来存储和管理应用中的状态。

import { ref ,watch} from 'vue'
//写这个函数是进行统一的暴露,为了避免下面return里面写多个
// initState 函数初始化了 store 中的默认状态，
function initState(){
    return{
        //收缩菜单这里使用的跨组件通信pinia
        isCollapse:false,
        tags:[
            {
                path:'/home',
                name:'home',
                label:'首页',
                icon:'home'
            }
        ],
        currentMenu:null,//当前选中的菜单项。左上角的小标签
        menuList:[],//存储所有菜单项。
        token:'',//存储登录的 token，用于身份验证。
        routerList:[]//存储动态路由列表。
    }
}

// 使用 defineStore 创建名为 'counter' 的 store，state 是一个响应式对象，存储了上述 initState 函数中的初始数据。
export const useAllDataStore = defineStore('counter', () => {
    // 使用setup方式
    // ref() 就是 state 属性
    // computed() 就是 getters
    // function() 就是 actions
    // 这里创建了一个名为 counter 的 Pinia store，state 是一个响应式对象，通过 initState() 初始化，ref() 用来创建响应式对象。
    const state = ref(initState())

    //通过watch监听state，来实现动态路由持久化
    watch(state,(newObj)=> {
        if(!newObj.token) return
        localStorage.setItem("store",JSON.stringify(newObj))
    },{deep:true})

    //用于判断是否向左上角添加标签
    // selectMenu 用于处理左侧菜单的选中状态和标签的添加。如果选择的是 "home"（首页），则 currentMenu 置为 null。否则，currentMenu 设为选中的菜单项，并判断该菜单项是否已经存在于 tags 数组中，如果没有则添加。
    function selectMenu(value){
        if(value.name === "home"){
            state.value.currentMenu = null
        }else{
            state.value.currentMenu = value  //给最上面首页右边添加路由标签
            //下面是判断tab里面是否有那个签，有就不添加，没有就添加
            //findIndex函数里面记得写return，因为它返回的是布尔值
            let index = state.value.tags.findIndex((item)=> { return item.name === value.name})
            index === -1 ? state.value.tags.push(value) : ''
        }
    }

    //下面的代码是关闭左上角的小标签
    function updateTags(tag){
        let index = state.value.tags.findIndex((item)=> {return item.name === tag.name})
        state.value.tags.splice(index,1)
    }
  
    //下面是登录后的页面跳转
    // updateMenuList 用于更新菜单项，value 传入的应该是新的菜单列表。该方法会覆盖 menuList 中的内容。
    function updateMenuList(value){
        state.value.menuList = value
    }

    //下面是动态路由的(这个难，多看看P33)
    // addMenu 用于动态地根据 menuList 配置添加路由。首先判断 type 是否为 "refresh"，如果是则从 localStorage 读取存储的状态并更新 state。接下来根据菜单项和 import.meta.glob 动态加载 Vue 组件，并生成相应的路由配置。最后移除现有的动态路由并重新注册新的路由。
    function addMenu(router,type){
        if(type === "refresh"){
            if(JSON.parse(localStorage.getItem("store"))){
                state.value = JSON.parse(localStorage.getItem("store"))
                //下面这句这一行的作用是确保重新加载路由之前，移除旧的路由。
                state.value.routerList=[]
            }else{
                return
            }
        }

        const menu = state.value.menuList //菜单
        const model = import.meta.glob("../views/**/*.vue") //返回一个模块对象，包含与模式匹配的所有 Vue 组件。这使得路由能够动态加载组件，而不是在编译时就固定所有组件。
        const routeArr = []
        menu.forEach((item)=>{
            if(item.children){
                item.children.forEach((val)=>{
                    let url = `../views/${val.url}.vue`
                    val.component = model[url]
                    routeArr.push(...item.children)
                })
            }else{
                let url = `../views/${item.url}.vue`
                item.component = model[url]
                routeArr.push(item)
            }
        })
        //下面是解决多账号登录数据混合显示的问题
        state.value.routerList = []
        let routers = router.getRoutes()//获取当前已注册的路由。
        routers.forEach(item => {
            if(item.name == "main" || item.name == "login" || item.name == "404"){
                // 如果路由的 name 是 'main' 或 'login'，则跳过当前的路由项，不进行任何处理
                return
            }else{
                router.removeRoute(item.name)
//如果路由的 name 是 "main"、"login" 或 "404"，这些是保留的基础路由，不需要移除。
// 否则，移除路由（即删除之前添加的动态路由）。
            }
        })

    routeArr.forEach((item)=>{
        state.value.routerList.push(router.addRoute("main",item))
    })
}

    //退出登陆时删数据
    function clean(){
        state.value.routerList.forEach(item => {
            console.log(item);
            
        if(item) item()//这个item()是remove方法
        })

        //重置数据加删除本地存储
        state.value = initState()
        localStorage.removeItem("store")
    }

    return {
        state,
        selectMenu,
        updateTags,
        updateMenuList,
        addMenu,
        clean
    }
  })